﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BusinessLogic
{
	[Serializable]
	public class KeyEntity : IKeyEntity
	{
		// ATTRIBUTS
		private readonly string _strID;
		public string ID
		{
			get { return _strID; }
			//set { _ID = value; }
		}		
		
		// CONSTRUCTEURS
		public KeyEntity( string strID )
		{
			this._strID			= strID;			
		}

		// METHODES

		public void Dispose()
		{
		}

		public bool IsValid()
		{
			return !string.IsNullOrEmpty( ID );
		}

		public override string ToString()
		{
			return _strID.ToString();
		}

		public object Clone()
		{
			return this.MemberwiseClone();
		}

		public override bool Equals(object oObj) 
		{
			if (ReferenceEquals(null, oObj))
				return false;

			if (ReferenceEquals(this, oObj)) 
				return true;

			if (oObj.GetType() != typeof(KeyEntity)) 
				return false;

			return Equals( (KeyEntity)oObj );
		}

		public bool Equals(IKeyEntity oObj) 
		{
			if (ReferenceEquals(null, oObj)) 
				return false;
			
			if (ReferenceEquals(this, oObj))
				return true;

			return oObj != null && oObj.ID == this.ID;
		}

		public override int GetHashCode() 
		{
			int result = _strID.GetHashCode();
			//result = (result*397) ^ (_strID_2 != null ? _strID.GetHashCode() : 0);
			//result = (result*397) ^ _strID_3.GetHashCode();
			//result = (result*397) ^ _strID_4.GetHashCode();
			return result;
		}

		public static bool operator==(KeyEntity k1, KeyEntity k2)
		{	
			if (ReferenceEquals(null, k1) ^ ReferenceEquals(null, k2)) 
				return false;

			if (ReferenceEquals(null, k1) && ReferenceEquals(null, k2)) 
				return true;			

			if( ReferenceEquals(k1,k2) )
				return true;
						
			return k1.Equals( k2 );
		}

		public static bool operator!=(KeyEntity k1, KeyEntity k2)
		{
			return !(k1 == k2);
		}

		public static bool operator==(KeyEntity k1, string k2)
		{	
			if( String.IsNullOrEmpty( k2 ) )
				return false;
				
			return k1.ToString().Equals( k2 );
		}

		public static bool operator!=(KeyEntity k1, string k2)
		{
			return !(k1 == k2);
		}

		public static implicit operator String(KeyEntity oKey)
		{
			return oKey.ToString();
		}
	}

	public static class FactoryEntity
	{
		public static IPersonneEntity GetPersonneEntity( IPersonneEntity oPersonneSrc )
		{
			return GetPersonneEntity( oPersonneSrc.Nom, oPersonneSrc.Prenom, oPersonneSrc.Age, oPersonneSrc.Adresse );
		}

		public static IPersonneEntity GetPersonneEntity( string strNom, string strPrenom, int nAge, string strAdresse )
		{
			return new PersonneEntity( strNom, strPrenom, nAge, strAdresse );
		}
	}

	[Serializable]
	public class PersonneEntity : IPersonneEntity
	{
		// ATTRIBUT
		private string _strNom;
		public string Nom
		{
			get { return _strNom; }
			set { _strNom = value; }
		}

		private string _strPrenom;
		public string Prenom
		{
		  get { return _strPrenom; }
		  set { _strPrenom = value; }
		}

		private int _nAge;
		public int Age
		{
			get { return _nAge; }
			set { _nAge = value; }
		}

		private string _strAdresse;
		public string Adresse
		{
			get { return _strAdresse; }
			set { _strAdresse = value; }
		}
		
		private readonly IKeyEntity _oCode;
		public IKeyEntity Code
		{
			get { return _oCode; }
		}

		public string NomTable
		{
			get { return "BusinessLogic.Personne"; }
		}
		

		// CONSTUCTEUR
		public PersonneEntity() : this( ""/*strNom*/, ""/*strPrenom*/, 0/*nAge*/, ""/*strAdresse*/)
		{
		}

		public PersonneEntity( string strNom, string strPrenom, int nAge, string strAdresse)
		{
			_strNom		= strNom;
			_strPrenom	= strPrenom;
			_nAge		= nAge;
			_strAdresse = strAdresse;

			_oCode = new KeyEntity( Guid.NewGuid().ToString() );
		}

		// METHODE
		public override bool Equals(object oObj) 
		{
			if (ReferenceEquals(null, oObj))
				return false;

			if (ReferenceEquals(this, oObj)) 
				return true;

			if (oObj.GetType() != typeof(PersonneEntity)) 
				return false;

			return Equals( (PersonneEntity)oObj );
		}

		public bool Equals(IEntityObject oObj) 
		{
			if (ReferenceEquals(null, oObj)) 
				return false;
			
			if (ReferenceEquals(this, oObj))
				return true;

			return oObj.Code == this.Code;

			/*
			return oObj			!= null 
				&& oObj.Nom		== this.Nom
				&& oObj.Prenom	== this.Prenom
				&& oObj.Age		== this.Age
				&& oObj.Adresse == this.Adresse;
			 */
		}

		public override int GetHashCode() 
		{
			int result	= Nom.GetHashCode();
			result		= (result*397) ^ (Prenom != null	? Prenom.GetHashCode()		: 0);
			result		= (result*397) ^ Age.GetHashCode();
			result		= (result*397) ^ (Adresse != null	? Adresse.GetHashCode()		: 0);			

			return result;
		}

		public void CopyTo( IPersonneEntity oObj)
		{
			oObj.Nom		= this.Nom;
			oObj.Prenom		= this.Prenom;
			oObj.Age		= this.Age;
			oObj.Adresse	= this.Adresse;
		}

		public object Clone()
		{
			return this.MemberwiseClone();
		}

		public void Dispose()
		{
			Code.Dispose();
		}

		public bool IsRecordable()
		{
			return Code.IsValid();
		}
	}
}
